/**
 ******************************************************************************
 * @file           : bsp_adc_config.h
 * @brief          : ADC Configuration File (STM32F1xx)
 ******************************************************************************
 * @attention
 *
 * ADC配置文件
 * 包含引脚定义、通道配置等硬件相关参数
 * 用户根据实际硬件修改此文件
 *
 ******************************************************************************
 */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __BSP_ADC_CONFIG_H
#define __BSP_ADC_CONFIG_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx.h"

/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/

/* ============================================================================ */
/*                       日志系统配置（改这里的数字）                             */
/* ============================================================================ */
/* 日志后端选择：1=EasyLogger, 2=printf, 0=关闭 */
#define ADC_USE_LOG     1

/* 根据配置自动定义日志宏 */
#if (ADC_USE_LOG == 1)
    /* 使用EasyLogger */
    #ifndef LOG_TAG
        #define LOG_TAG    "ADC"
    #endif
    #include "elog.h"
    
#elif (ADC_USE_LOG == 2)
    /* 使用printf */
    #include <stdio.h>
    #define log_i(fmt, ...)     printf(fmt "\r\n", ##__VA_ARGS__)
    #define log_w(fmt, ...)     printf("[WARN] " fmt "\r\n", ##__VA_ARGS__)
    #define log_e(fmt, ...)     printf("[ERROR] " fmt "\r\n", ##__VA_ARGS__)
    #define log_d(fmt, ...)     printf("[DEBUG] " fmt "\r\n", ##__VA_ARGS__)
    
#else
    /* 关闭日志 */
    #define log_i(fmt, ...)
    #define log_w(fmt, ...)
    #define log_e(fmt, ...)
    #define log_d(fmt, ...)
#endif

/* ============================================================================ */
/*                      ADC选择配置（改这里即可切换ADC）                         */
/* ============================================================================ */
/**
 * @brief ADC选择（1=ADC1, 2=ADC2, 3=ADC3）
 * 
 * 修改此值即可切换使用的ADC，DMA通道会自动配置
 * 
 * STM32F1 ADC资源：
 *   ADC1: 12位精度，支持DMA（DMA1_CH1）【推荐】
 *   ADC2: 12位精度，不支持DMA（仅轮询/中断模式）
 *   ADC3: 12位精度，支持DMA（DMA2_CH5）（仅大容量型号）
 * 
 * 注意：
 * - ADC2不支持DMA，选择ADC2会禁用DMA功能
 * - ADC3仅STM32F103xE/xG大容量型号支持
 */
#define ADC_SELECT_NUM                  1       /*!< 选择使用的ADC号 */

/* ============================================================================ */
/*                    自动配置区域（请勿手动修改）                                */
/* ============================================================================ */

/* --------------------------------------------------------------------------- */
/* ADC1 配置 (DMA1_Channel1)                                                 */
/* --------------------------------------------------------------------------- */
#if (ADC_SELECT_NUM == 1)
    #define ADC_ADCx                        ADC1
    #define ADC_ADCx_CLK_ENABLE()           do{ __HAL_RCC_ADC1_CLK_ENABLE(); }while(0)
    
    /* ADC1固定使用DMA1_Channel1 */
    #define ADC_DMAx                        DMA1
    #define ADC_DMAx_CHANNELx               DMA1_Channel1
    #define ADC_DMAx_CHANNELx_IRQn          DMA1_Channel1_IRQn
    #define ADC_DMA_CLK_ENABLE()            do{ __HAL_RCC_DMA1_CLK_ENABLE(); }while(0)
    
    #define ADC_SUPPORT_DMA                 1   /* ADC1支持DMA */

/* --------------------------------------------------------------------------- */
/* ADC2 配置 (不支持DMA)                                                  */
/* --------------------------------------------------------------------------- */
#elif (ADC_SELECT_NUM == 2)
    #define ADC_ADCx                        ADC2
    #define ADC_ADCx_CLK_ENABLE()           do{ __HAL_RCC_ADC2_CLK_ENABLE(); }while(0)
    
    /* ADC2不支持DMA */
    #define ADC_SUPPORT_DMA                 0   /* ADC2不支持DMA */
    
    #warning "ADC2 does not support DMA, polling mode will be used (low performance)"

/* --------------------------------------------------------------------------- */
/* ADC3 配置 (DMA2_Channel5, 仅大容量型号)                           */
/* --------------------------------------------------------------------------- */
#elif (ADC_SELECT_NUM == 3)
    #define ADC_ADCx                        ADC3
    #define ADC_ADCx_CLK_ENABLE()           do{ __HAL_RCC_ADC3_CLK_ENABLE(); }while(0)
    
    /* ADC3固定使用DMA2_Channel5 */
    #define ADC_DMAx                        DMA2
    #define ADC_DMAx_CHANNELx               DMA2_Channel5
    #define ADC_DMAx_CHANNELx_IRQn          DMA2_Channel4_5_IRQn
    #define ADC_DMA_CLK_ENABLE()            do{ __HAL_RCC_DMA2_CLK_ENABLE(); }while(0)
    
    #define ADC_SUPPORT_DMA                 1   /* ADC3支持DMA */

#else
    #error "ADC_SELECT_NUM must be 1~3!"
#endif

/* ============================================================================ */
/*                          硬件配置（用户可修改）                               */
/* ============================================================================ */

/* ============================================================================ */
/*                          通道配置（用户可修改）                               */
/* ============================================================================ */

/* ADC通道数量 */
#define ADC_CHANNEL_NUM                 2                   /*!< ADC采集通道数量 */

/* ADC通道类型定义 */
typedef enum
{
    ADC_CH_TYPE_EXTERNAL = 0,   /*!< 外部通道（需要GPIO） */
    ADC_CH_TYPE_INTERNAL = 1    /*!< 内部通道（温度、VREF） */
} ADC_Channel_Type_e;

/* ADC通道配置结构体 */
typedef struct
{
    uint32_t channel;           /*!< ADC通道号（HAL定义） */
    ADC_Channel_Type_e type;    /*!< 通道类型 */
    GPIO_TypeDef *gpio_port;    /*!< GPIO端口（外部通道） */
    uint16_t gpio_pin;          /*!< GPIO引脚（外部通道） */
} ADC_Channel_Config_t;

/* 
 * ADC通道配置表（按DMA扫描顺序）
 * 
 * 重要说明：
 * 1. 配置表的顺序 = DMA扫描顺序 = 数组索引顺序
 * 2. 通道0是第一个扫描的，通道1是第二个扫描的，以此类推
 * 3. 修改顺序时，必须同步修改APP层的通道索引定义（ADC_CH_xxx）
 * 
 * 配置规则：
 * - 内部通道：type=ADC_CH_TYPE_INTERNAL，gpio_port和gpio_pin填NULL/0
 * - 外部通道：type=ADC_CH_TYPE_EXTERNAL，配置对应的GPIO
 * - 增删通道：修改ADC_CHANNEL_NUM和此表即可
 */
#define ADC_CHANNEL_CONFIG_TABLE \
{ \
    /* 通道0：PC4 - 外部传感器 */ \
    {ADC_CHANNEL_14, ADC_CH_TYPE_EXTERNAL, GPIOC, GPIO_PIN_4}, \
    /* 通道1：内部参考电压（用于VDDA校准） */ \
    {ADC_CHANNEL_VREFINT, ADC_CH_TYPE_INTERNAL, NULL, 0} \
    /* 如需添加温度传感器，取消注释下一行，并修改ADC_CHANNEL_NUM为3 */ \
    /* {ADC_CHANNEL_TEMPSENSOR, ADC_CH_TYPE_INTERNAL, NULL, 0} */ \
}

/* ============================================================================ */
/*                          功能配置（用户可修改）                               */
/* ============================================================================ */

/* ADC分辨率 */
#define ADC_RESOLUTION                  12                  /*!< ADC分辨率(12位) */
#define ADC_MAX_VALUE                   4095                /*!< ADC最大值(2^12-1) */

/* ADC参考电压 */
#define ADC_VREF                        3.3f                /*!< ADC参考电压(V) */

/* ADC采样时间 */
#define ADC_SAMPLE_TIME                 ADC_SAMPLETIME_239CYCLES_5  /*!< 采样时间 */

/* ADC平均采样次数 */
#define ADC_AVERAGE_TIMES               20                          /*!< 单次读取平均采样次数 */

/* ADC DMA缓冲区大小 */
#define ADC_DMA_BUF_SIZE                (50 * ADC_CHANNEL_NUM)      /*!< DMA缓冲区大小(50次×通道数) */

/* ADC滤波配置 */
#define ADC_FILTER_ENABLE               1                           /*!< ADC滤波功能使能 (0:禁用, 1:启用) */
#define ADC_FILTER_ALPHA                0.2f                        /*!< 一阶低通滤波系数α (0.0~1.0，越小越平滑) */

/* 温度传感器参数 */
#define ADC_TEMP_V25                    1.43f               /*!< 25℃时温度传感器电压(V) */
#define ADC_TEMP_AVG_SLOPE              0.0043f             /*!< 温度传感器斜率(V/℃) */

/* Exported macro ------------------------------------------------------------*/
/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/

/* ============================================================================ */
/*                          编译期配置检查                                      */
/* ============================================================================ */

/* 检查通道数量是否超限 */
#if (ADC_CHANNEL_NUM > 16)
    #error "ADC_CHANNEL_NUM must be <= 16! Please reduce ADC_CHANNEL_NUM value"
#endif

/* 检查ADC2是否试图使用DMA */
#if (ADC_SELECT_NUM == 2) && (ADC_CHANNEL_NUM > 1)
    #error "ADC2 does not support DMA! Multi-channel sampling is slow. Please use ADC1 or ADC3"
#endif

#ifdef __cplusplus
}
#endif

#endif /* __BSP_ADC_CONFIG_H */
